/*
	Copyright (C) 2019 Zongming Liu <1849059316@qq.com>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License along
	with this program; if not, write to the Free Software Foundation, Inc.,
	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

#ifndef VertexType_h__
#define VertexType_h__

/************************************************************************/
/* 预定义的顶点类型
*/
/************************************************************************/

#include "Vector.h"
#include "Color.h"
#include <d3d11.h>

#include "../utility/MacroTool.h"

namespace SkyEngine2d
{

	/////////////////////////////Position//////////////////////////////////////////////

	struct SGE_API VertexPosition
	{
		VertexPosition()
			:position(0, 0, 0) {}

		VertexPosition(const Vector3& position)
			:position(position) {}


		Vector3  position;

		static const int InputElementCount = 1;
		static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
	};

	__declspec(selectany) const D3D11_INPUT_ELEMENT_DESC VertexPosition::InputElements[] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};

	/////////////////////////PositionColor///////////////////////////////////////

	struct SGE_API VertexPositionColor
	{
		VertexPositionColor()
			:color(0, 0, 0), position(0, 0, 0) {}


		VertexPositionColor(const Vector3& position, const Color4f& color)
			: position(position),
			color(color)
		{ }

		VertexPositionColor(const Vector2& position, const Color4f& color)
			: position(position.x, position.y, 0.5f),
			color(color)
		{ }

		VertexPositionColor(DirectX::FXMVECTOR position, DirectX::FXMVECTOR color)
		{
			XMStoreFloat3(&this->position, position);
			XMStoreFloat4(&this->color, color);
		}

		Vector3		position;
		Color4f		color;

		static const int InputElementCount = 2;
		static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
	};

	__declspec(selectany) const D3D11_INPUT_ELEMENT_DESC VertexPositionColor::InputElements[VertexPositionColor::InputElementCount] = {
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT,    0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
	};

	///////////////////////////Position texture ////////////////////////////////////////

	struct SGE_API VertexPositionTexture
	{
		Vector3 position;
		Vector2 tex;

		VertexPositionTexture(const Vector2& position, const Vector2& tex)
			:position(position.x, position.y, 0.5f), tex(tex) {}

		VertexPositionTexture(const Vector3& position, const Vector2& tex)
			:position(position), tex(tex) {}

		static const int InputElementCount = 2;
		static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
	};

	__declspec(selectany) const D3D11_INPUT_ELEMENT_DESC VertexPositionTexture::InputElements[VertexPositionTexture::InputElementCount] = {
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};

	///////////////////////////Position color texture /////////////////////////////////////////

	struct SGE_API VertexPositionColorTexture
	{
		Vector3 position;
		Color4f color;
		Vector2 tex;   //纹理坐标

		VertexPositionColorTexture()
			:position(0, 0, 0)
			, color(0, 0, 0, 0)
			, tex(0, 0) {}

		VertexPositionColorTexture(const Vector3& position, const Color4f& color, const Vector2& tex)
			: position(position)
			, color(color)
			, tex(tex)
		{ }

		VertexPositionColorTexture(const Vector2& position, const Color4f& color, const Vector2& tex)
			:position(position.x, position.y, 0.5f)
			, color(color)
			, tex(tex)
		{ }

		VertexPositionColorTexture(DirectX::FXMVECTOR position, DirectX::FXMVECTOR color, DirectX::FXMVECTOR tex)
		{
			XMStoreFloat3(&this->position, position);
			XMStoreFloat4(&this->color, color);
			XMStoreFloat2(&this->tex, tex);
		}

		static const int InputElementCount = 3;
		static const D3D11_INPUT_ELEMENT_DESC InputElements[InputElementCount];
	};

	__declspec(selectany) const D3D11_INPUT_ELEMENT_DESC VertexPositionColorTexture::InputElements[VertexPositionColorTexture::InputElementCount] =
	{
		{ "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "COLOR",    0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0,12, D3D11_INPUT_PER_VERTEX_DATA, 0 },
		{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 28, D3D11_INPUT_PER_VERTEX_DATA, 0 }
	};
}


//////////////////////////////////////////////////////////////////////////////////


#endif // VertexType_h__
